home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
progjour
/
1989
/
02
/
pwcomm1
/
ttycls.c
< prev
next >
Wrap
Text File
|
1988-12-04
|
8KB
|
326 lines
/*
* TTYCLS module
*
* Written by Bill Hall
* 3665 Benton Street, #66
* Santa Clara, CA 95051
*
* This file supports a teletype style window in either Microsoft
* windows or Presentation Manager.
*
* For an example of its use, see the source code for WINAUX
* or PMAUX.
*
* If being used in a Windows program, be sure to define WINDOWS
*/
#ifdef WINDOWS
#define NOCOMM /* stops a bunch of unneeded level 3 warnings */
#include <windows.h>
#else
#define INCL_PM
#include <os2.h>
extern HAB hAB; /* these should be defined in the main program */
extern HHEAP hHeap;
#endif
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "ascii.h"
#include "ttycls.h"
/* local functions */
static void NEAR DoLF(PTTYWND pTTYWnd);
static void NEAR DoCR(PTTYWND pTTYWnd);
static void NEAR DoBS(PTTYWND pTTYWnd);
static void NEAR DoTab(PTTYWND pTTYWnd);
/*
* Called at create window time. Creates a text buffer based
* on the passed in width, height, and the character width and height.
* Other parameters such as wrap, character mask, etc. are also set.
*/
InitTTYWindow(pTTYWnd,left,top,width,height,charwidth,charheight,LFonCR,CRonLF,
wrap,mask)
PTTYWND pTTYWnd;
short left, top, width, height, charwidth, charheight;
BOOL LFonCR, CRonLF, wrap;
BYTE mask;
{
int bufsize;
pTTYWnd->Left = left;
pTTYWnd->Top = top;
pTTYWnd->Width = width;
pTTYWnd->Height = height;
pTTYWnd->CWidth = charwidth;
pTTYWnd->CHeight = charheight;
pTTYWnd->MaxLines = height / charheight;
pTTYWnd->MaxCols = width / charwidth;
pTTYWnd->MaxLineLength = pTTYWnd->MaxCols + 1;
bufsize = pTTYWnd->MaxLines * pTTYWnd->MaxLineLength;
/* allocate space for the display characters */
/* if allocation successful, initialize the remaining tty data */
#ifdef WINDOWS
if (pTTYWnd->hVidBuf = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, bufsize)) {
pTTYWnd->pVidBuf = LocalLock(pTTYWnd->hVidBuf); /* lock the buffer */
pTTYWnd->Pos.y = (pTTYWnd->MaxLines - 1) * charheight - 1;
#else
if (pTTYWnd->pVidBuf = WinAllocMem(hHeap, bufsize)) {
memset(pTTYWnd->pVidBuf, NUL, bufsize);
pTTYWnd->Pos.y = 1;
#endif
pTTYWnd->Pos.x = 0;
pTTYWnd->oCurrentLine = pTTYWnd->CurLineOffset = 0;
pTTYWnd->oVidLastLine = (pTTYWnd->MaxLines-1) * pTTYWnd->MaxLineLength;
pTTYWnd->LFonCR = LFonCR;
pTTYWnd->CRonLF = CRonLF;
pTTYWnd->Wrap = wrap;
pTTYWnd->ebitmask = mask;
return TRUE;
}
return FALSE;
}
/* display the characters contained in str */
int NEAR TTYDisplay(PTTYWND pTTYWnd, short len, BYTE *str)
{
HPS hPS;
register BYTE *ptr;
register short ctr;
short toff, txpos;
BYTE *tbuf;
short cols = pTTYWnd->MaxCols;
short cwidth = pTTYWnd->CWidth;
BYTE mask = pTTYWnd->ebitmask;
while (len) {
ptr = str;
ctr = 0;
txpos = (short)pTTYWnd->Pos.x;
tbuf = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
toff = pTTYWnd->CurLineOffset;
while((*ptr &= mask) >= SP) {
if ((len) && (toff < cols)) {
ctr += 1;
*(tbuf + toff++) = *ptr++;
txpos += cwidth;
len -= 1;
}
else
break;
}
if (ctr) {
#ifdef WINDOWS
hPS = GetDC(pTTYWnd->hWnd);
TextOut(hPS, pTTYWnd->Pos.x, pTTYWnd->Pos.y, (LPSTR)str, ctr);
ReleaseDC(pTTYWnd->hWnd, hPS);
#else
hPS = WinGetPS(pTTYWnd->hWnd);
GpiSetBackMix(hPS, BM_OVERPAINT);
GpiCharStringAt(hPS,(PPOINTL)&pTTYWnd->Pos,(LONG)ctr,(PCH)str);
GpiRestorePS(hPS, -1L);
WinReleasePS (hPS);
#endif
if (toff < cols) {
pTTYWnd->CurLineOffset = toff;
#ifdef WINDOWS
pTTYWnd->Pos.x = txpos;
#else
pTTYWnd->Pos.x = (LONG)txpos;
#endif
}
else
if (pTTYWnd->Wrap) {
DoCR(pTTYWnd);
DoLF(pTTYWnd);
}
}
while ((*ptr &= mask) < SP) {
if (len) {
switch(*ptr) {
case BEL:
#ifdef WINDOWS
MessageBeep(0);
#else
WinAlarm(HWND_DESKTOP, WA_ERROR);
#endif
break;
case HT:
DoTab(pTTYWnd);
break;
case CR:
DoCR(pTTYWnd);
if (pTTYWnd->LFonCR)
DoLF(pTTYWnd);
break;
case LF:
if (pTTYWnd->CRonLF)
DoCR(pTTYWnd);
DoLF(pTTYWnd);
break;
case BS:
DoBS(pTTYWnd);
break;
}
len -= 1;
ptr++;
}
else
break;
}
str = ptr;
}
return (len);
}
/* perform a carriage return */
static void NEAR DoCR(PTTYWND pTTYWnd)
{
pTTYWnd->CurLineOffset = 0;
pTTYWnd->Pos.x = 0;
}
/* perform a line feed */
static void NEAR DoLF(PTTYWND pTTYWnd)
{
BYTE *pCurr;
short offset, cols;
int i;
HWND hWnd = pTTYWnd->hWnd;
cols = pTTYWnd->MaxCols;
if ((pTTYWnd->oCurrentLine+=pTTYWnd->MaxLineLength) > pTTYWnd->oVidLastLine)
pTTYWnd->oCurrentLine = 0;
pCurr = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
offset = pTTYWnd->CurLineOffset;
for (i = 0; i < offset; i++)
*(pCurr + i) = SP;
for (i = offset; i < cols; i++)
*(pCurr + i) = NUL;
#ifdef WINDOWS
ScrollWindow(hWnd,0,-pTTYWnd->CHeight,(LPRECT)NULL,(LPRECT)NULL);
UpdateWindow(hWnd);
#else
WinScrollWindow(hWnd,0,pTTYWnd->CHeight,
NULL,NULL,NULL,NULL,SW_INVALIDATERGN);
WinUpdateWindow(hWnd);
#endif
}
/* perform a backspace */
static void NEAR DoBS(PTTYWND pTTYWnd)
{
if (pTTYWnd->CurLineOffset > 0) {
#ifdef WINDOWS
pTTYWnd->Pos.x -= pTTYWnd->CWidth;
#else
pTTYWnd->Pos.x -= (LONG)pTTYWnd->CWidth;
#endif
pTTYWnd->CurLineOffset -= 1;
}
}
/* Horizontal tab */
static void NEAR DoTab(pTTYWnd)
PTTYWND pTTYWnd;
{
short curoffset, xpos, ypos, cols, cwidth;
BYTE *pCurr;
#ifdef WINDOWS
RECT myrect;
#else
RECTL myrect;
#endif
cols = pTTYWnd->MaxCols;
curoffset = pTTYWnd->CurLineOffset;
cwidth = pTTYWnd->CWidth;
if (curoffset < (cols - 1)) {
xpos = (short)pTTYWnd->Pos.x; /* initialize variables */
ypos = (short)pTTYWnd->Pos.y;
pCurr = pTTYWnd->pVidBuf + pTTYWnd->oCurrentLine;
do {
if (*(pCurr + curoffset) == NUL) /* if null, replace with space */
*(pCurr + curoffset) = SP;
curoffset += 1; /* update offsets */
xpos += cwidth;
} while ((curoffset % 8 != 0) && (curoffset < (cols - 1)));
/* now invalidate the part of the screen affected */
#ifdef WINDOWS
SetRect((LPRECT)&myrect, xpos, ypos, pTTYWnd->Width, pTTYWnd->Height);
InvalidateRect(pTTYWnd->hWnd, (LPRECT)&myrect, TRUE);
#else
WinSetRect(hAB,&myrect,xpos,ypos,pTTYWnd->Width,ypos+pTTYWnd->CHeight);
WinInvalidateRect(pTTYWnd->hWnd, &myrect, TRUE);
#endif
/* finally, reset the tty window variables */
pTTYWnd->Pos.x = xpos;
pTTYWnd->CurLineOffset = curoffset;
}
}
/* repaint the window */
void NEAR TTYWndPaint(PTTYWND pTTYWnd, HPS hPS, short top, short bottom)
{
#ifdef WINDOWS
POINT pt;
short wtop;
#else
POINTL pt;
#endif
BYTE *lineptr;
BYTE *pBuf, *pEnd;
short lines, length;
short cheight;
int i;
#ifndef WINDOWS
GpiErase (hPS);
#endif
pt.x = 0;
pBuf = pTTYWnd->pVidBuf;
pEnd = pBuf + pTTYWnd->oVidLastLine;
lineptr = pBuf + pTTYWnd->oCurrentLine;
pt.y = pTTYWnd->Pos.y;
length = pTTYWnd->MaxLineLength;
cheight = pTTYWnd->CHeight;
#ifdef WINDOWS
wtop = pTTYWnd->Height - top;
lines = wtop / cheight;
if (wtop % cheight)
lines += 1;
lines = min(pTTYWnd->MaxLines, lines);
#else
lines = top / cheight;
if (top % cheight)
lines += 1;
lines = min(pTTYWnd->MaxLines, lines);
#endif
for (i = 0; i < lines; i++) {
#ifdef WINDOWS
TextOut(hPS, pt.x, pt.y, (LPSTR)lineptr, strlen(lineptr));
pt.y -= cheight;
#else
GpiCharStringAt(hPS,&pt,(LONG)strlen(lineptr),(PCH)lineptr);
pt.y += (LONG)cheight;
#endif
if ((lineptr -= length) < pBuf)
lineptr = pEnd;
}
}